// utils/websocket.js

import {
  showNotification
} from '../utils/notification.js'

export class SSEWebSocket {
  constructor(accessToken) {
    this.accessToken = accessToken;
    // 使用动态地址，从本地存储获取基础地址
    this.url = this.getWebSocketUrl(accessToken);

    this.ws = null;
    this.isConnected = false;
    this.isManualClose = false; // 是否手动关闭（用于判断是否自动重连）

    this.reconnectDelay = 3000; // 重连间隔（ms）
    this.maxReconnectAttempts = 10;
    this.reconnectAttempts = 0;

    this.heartbeatInterval = 30 * 1000; // 30秒心跳
    this.heartbeatTimer = null;

    this.eventCallbacks = {}; // 事件监听 { eventName: [callback1, callback2] }

    this.connect();
  }

  /**
   * 获取WebSocket URL，支持动态地址
   */
  getWebSocketUrl(accessToken) {
    const baseUrl = uni.getStorageSync('baseUrl')
    if (baseUrl) {
      // 使用存储的地址，添加WebSocket协议
      return `ws://${baseUrl}?accessToken=${accessToken}`
    } else {
      // 使用默认地址
      const defaultUrl = '192.168.2.87:8881/api'
      return `ws://${defaultUrl}?accessToken=${accessToken}`
    }
  }

  /**
   * 建立 WebSocket 连接
   */
  connect() {
    if (this.ws) {
      this.ws.close();
    }

    console.log(`正在连接 WebSocket: ${this.url}`);
    // 注意：uni.connectSocket 在 App/H5 都支持
    this.ws = uni.connectSocket({
      url: this.url,
      success: (res) => {
        console.log('WebSocket 连接请求已发送', res);
      },
      fail: (err) => {
        console.error('WebSocket 连接失败', err);
        this.reconnect();
      }
    });

    this.bindEvents();
  }

  /**
   * 绑定事件监听
   */
  bindEvents() {
    uni.onSocketOpen((res) => {
      console.log('WebSocket 已连接', res);
      this.isConnected = true;
      this.isManualClose = false;
      this.reconnectAttempts = 0;

      // 启动心跳
      this.startHeartbeat();

      // 触发 open 事件
      this.emit('open');
    });

    uni.onSocketMessage((res) => {
      const data = res.data;
      console.log('收到 WebSocket 消息:', data);

      //监听到信息后解析并发送通知 
      try {
        const message = JSON.parse(data);

        // 检查是否是语音对讲接听消息 (code === 101)
        if (message.body && message.body.code === 101) {
          console.log('收到语音对讲接听消息，code:', message.body.code);


          uni.showToast({
            title: '对方已接听您的呼叫',
            icon: 'success',
            duration: 3000
          });

          // 延迟退出当前页面
          setTimeout(() => {
            // 检查当前页面是否是语音对讲页面
            const pages = getCurrentPages();
            const currentPage = pages[pages.length - 1];

            if (currentPage && currentPage.route && currentPage.route.includes('intercom')) {
              console.log('退出语音对讲页面');
              uni.navigateBack();
            }
          }, 1000);

          return;
        }

        if (message.type !== 'SEND_TO_ALL_REQUEST' && message.type !== 'SEND_TO_GROUP_REQUEST' && message.type !==
          'SEND_TO_ONE_REQUEST' && message.type !== 'SEND_TO_USER_REQUEST') {
          return
        } else {
          uni.setStorageSync('nitificaValue', message.body.content)
          showNotification()
        }
        this.handleMessage(message);
      } catch (e) {
        console.warn('消息解析失败，非JSON:', data);
      }
    });

    uni.onSocketError((err) => {
      console.error('WebSocket 错误:', err);
      this.isConnected = false;
      this.emit('error', err);
      this.reconnect();
    });

    uni.onSocketClose((res) => {
      console.log('WebSocket 已关闭:', res);
      this.isConnected = false;
      this.clearHeartbeat();

      this.emit('close', res);

      if (!this.isManualClose) {
        this.reconnect();
      }
    });
  }

  /**
   * 处理收到的消息
   */
  handleMessage(message) {
    const {
      type,
      body
    } = message;

    // if (!body || !body.toUser) {
    //   console.warn('消息缺少 body 或 toUser 字段', message);
    //   return;
    // }

    // 只处理发给自己的消息
    if (body.toUser !== this.accessToken) {
      // console.log(`忽略消息：不是发给我的 (toUser=${body.toUser})`);
      return;
    }

    // 根据 type 分发事件
    switch (message.type) {
      case 'SEND_TO_ONE_REQUEST':
        this.emit('message', {
          msgId: body.msgId,
          content: body.content,
          from: body.fromUser || 'unknown',
          timestamp: Date.now()
        });
        break;

      case 'PONG':
        // 心跳响应
        break;

      default:
        console.log('未知消息类型:', type, message);
        this.emit('unknown', message);
    }
  }

  /**
   * 发送消息
   */
  send(message) {
    if (!this.isConnected || !this.ws) {
      console.warn('WebSocket 未连接，无法发送消息');
      return;
    }

    try {
      uni.sendSocketMessage({
        data: JSON.stringify(message),
        success: () => console.log('消息已发送:', message),
        fail: (err) => console.error('消息发送失败:', err)
      });
    } catch (e) {
      console.error('发送消息异常:', e);
    }
  }

  /**
   * 启动心跳
   */
  startHeartbeat() {
    this.clearHeartbeat();
    this.heartbeatTimer = setInterval(() => {
      if (this.isConnected) {
        this.send({
          type: 'PING',
          body: {
            userId: uni.getStorageSync('deviceNo'),
            content: '握握手'
          }
        });
      }
    }, this.heartbeatInterval);
  }

  /**
   * 清除心跳
   */
  clearHeartbeat() {
    if (this.heartbeatTimer) {
      clearInterval(this.heartbeatTimer);
      this.heartbeatTimer = null;
    }
  }

  /**
   * 重连机制
   */
  reconnect() {
    if (this.isManualClose || this.reconnectAttempts >= this.maxReconnectAttempts) {
      console.log('停止重连');
      return;
    }

    this.reconnectAttempts++;
    console.log(`准备第 ${this.reconnectAttempts} 次重连...`);

    setTimeout(() => {
      this.connect();
    }, this.reconnectDelay);
  }

  /**
   * 注册事件监听
   * 支持: 'open', 'close', 'error', 'message', 'unknown'
   */
  on(event, callback) {
    if (!this.eventCallbacks[event]) {
      this.eventCallbacks[event] = [];
    }
    this.eventCallbacks[event].push(callback);
  }

  /**
   * 移除事件监听
   */
  off(event, callback) {
    if (this.eventCallbacks[event]) {
      this.eventCallbacks[event] = this.eventCallbacks[event].filter(cb => cb !== callback);
    }
  }

  /**
   * 触发事件
   */
  emit(event, data) {
    if (this.eventCallbacks[event]) {
      this.eventCallbacks[event].forEach(cb => cb(data));
    }
  }

  /**
   * 手动关闭连接（不自动重连）
   */
  close() {
    this.isManualClose = true;
    this.clearHeartbeat();
    if (this.ws) {
      uni.closeSocket();
    }
    console.log('WebSocket 已手动关闭');
  }
}

export default SSEWebSocket;